import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';

import SysDictionary from '@main/entities/service/admin/sys/sys-dictionary.entity';
import SysDictionaryType from '@main/entities/service/admin/sys/sys-dictionary-type.entity';
import { Repository, Like, In } from 'typeorm';
import { ApiException } from '@main/common/exceptions/api.exception';
import { SysOperationLogService } from '../operationLog/operationLog.service';

@Injectable()
export class SysDictionaryService {
  constructor(
    @InjectRepository(SysDictionary)
    private dictionaryRepository: Repository<SysDictionary>,
    @InjectRepository(SysDictionaryType)
    private dictionaryTypeRepository: Repository<SysDictionaryType>,
    private operationLogService: SysOperationLogService
  ) {
    this.initDictionary();
  }

  async initDictionary() {
    const dictionaryTypeList = await this.dictionaryTypeRepository.find();

    if (dictionaryTypeList.length === 0) {
      console.log('初始化字典表数据');

      this.dictionaryTypeRepository.insert([
        {
          dictionaryTypeName: '楞别',
          dictionaryTypeCode: 'corrugated_type',
        },
        {
          dictionaryTypeName: '箱型',
          dictionaryTypeCode: 'carton_type',
        },
        {
          dictionaryTypeName: '出条方式',
          dictionaryTypeCode: 'out_mode',
        },
        {
          dictionaryTypeName: '工单状态',
          dictionaryTypeCode: 'order_status',
        },
        {
          dictionaryTypeName: '单据来源',
          dictionaryTypeCode: 'order_source',
        },
        {
          dictionaryTypeName: '客户类型',
          dictionaryTypeCode: 'customer_type',
        },
        {
          dictionaryTypeName: '停机原因组',
          dictionaryTypeCode: 'downtime_reason_groud',
        },
        {
          dictionaryTypeName: '不良缺陷等级',
          dictionaryTypeCode: 'bad_level',
        },
        {
          dictionaryTypeName: '报警状态',
          dictionaryTypeCode: 'alarm_status',
        },
        {
          dictionaryTypeName: '报警类型',
          dictionaryTypeCode: 'alarm_type',
        },
        {
          dictionaryTypeName: '班次',
          dictionaryTypeCode: 'shift_time_type',
        },
        {
          dictionaryTypeName: '保养类型',
          dictionaryTypeCode: 'maintenance_period_type',
        },
        {
          dictionaryTypeName: '设备类型',
          dictionaryTypeCode: 'machine_type',
        },
        {
          dictionaryTypeName: '是否已保养',
          dictionaryTypeCode: 'is_maintain',
        },
        {
          dictionaryTypeName: '保养状态',
          dictionaryTypeCode: 'maintenance_status',
        },
        {
          dictionaryTypeName: '水墨分类',
          dictionaryTypeCode: 'ink_painting_type',
        },
      ]);

      this.dictionaryRepository.insert([
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'A',
          dictionaryCode: 'A',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'B',
          dictionaryCode: 'B',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'E',
          dictionaryCode: 'E',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'C',
          dictionaryCode: 'C',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'AB',
          dictionaryCode: 'AB',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'BE',
          dictionaryCode: 'BE',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'BC',
          dictionaryCode: 'BC',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'corrugated_type',
          languageType: 'zh',
          dictionaryName: 'ABE',
          dictionaryCode: 'ABE',
          extend1: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'carton_type',
          languageType: 'zh',
          dictionaryName: 'A',
          dictionaryCode: 'A',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'carton_type',
          languageType: 'zh',
          dictionaryName: 'C',
          dictionaryCode: 'C',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'carton_type',
          languageType: 'zh',
          dictionaryName: 'D',
          dictionaryCode: 'D',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'carton_type',
          languageType: 'zh',
          dictionaryName: 'E',
          dictionaryCode: 'E',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_status',
          languageType: 'zh',
          dictionaryName: '待开工',
          dictionaryCode: '20',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_status',
          languageType: 'zh',
          dictionaryName: '生产中',
          dictionaryCode: '30',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_status',
          languageType: 'zh',
          dictionaryName: '完工',
          dictionaryCode: '40',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_status',
          languageType: 'zh',
          dictionaryName: '废止',
          dictionaryCode: '50',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_status',
          languageType: 'zh',
          dictionaryName: '暂停',
          dictionaryCode: '60',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_source',
          languageType: 'zh',
          dictionaryName: '手动',
          dictionaryCode: '01',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'order_source',
          languageType: 'zh',
          dictionaryName: 'erp',
          dictionaryCode: '02',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'out_mode',
          languageType: 'zh',
          dictionaryName: '正唛',
          dictionaryCode: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'out_mode',
          languageType: 'zh',
          dictionaryName: '侧唛',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'downtime_reason_groud',
          languageType: 'zh',
          dictionaryName: '停机',
          dictionaryCode: '10',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'downtime_reason_groud',
          languageType: 'zh',
          dictionaryName: '维护',
          dictionaryCode: '20',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'bad_level',
          languageType: 'zh',
          dictionaryName: '一般缺陷',
          dictionaryCode: '10',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'bad_level',
          languageType: 'zh',
          dictionaryName: '轻微缺陷',
          dictionaryCode: '20',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'bad_level',
          languageType: 'zh',
          dictionaryName: '严重缺陷',
          dictionaryCode: '30',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'bad_level',
          languageType: 'zh',
          dictionaryName: '致命缺陷',
          dictionaryCode: '40',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'alarm_status',
          languageType: 'zh',
          dictionaryName: '实时',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'alarm_status',
          languageType: 'zh',
          dictionaryName: '历史',
          dictionaryCode: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'alarm_type',
          languageType: 'zh',
          dictionaryName: '警告',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'alarm_type',
          languageType: 'zh',
          dictionaryName: '故障',
          dictionaryCode: '2',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'shift_time_type',
          languageType: 'zh',
          dictionaryName: '早班',
          dictionaryCode: '1',
          extend1: '08:30',
          extend2: '17:00',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'shift_time_type',
          languageType: 'zh',
          dictionaryName: '晚班',
          dictionaryCode: '2',
          extend1: '20:30',
          extend2: '08:00',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'maintenance_period_type',
          languageType: 'zh',
          dictionaryName: '月',
          dictionaryCode: '30',
          sort: 1,
        },
        {
          dictionaryTypeCode: 'maintenance_period_type',
          languageType: 'zh',
          dictionaryName: '日',
          dictionaryCode: '10',
          sort: 2,
        },
        {
          dictionaryTypeCode: 'maintenance_period_type',
          languageType: 'zh',
          dictionaryName: '周',
          dictionaryCode: '20',
          sort: 3,
        },
        {
          dictionaryTypeCode: 'maintenance_period_type',
          languageType: 'zh',
          dictionaryName: '季度',
          dictionaryCode: '40',
          sort: 4,
        },
        {
          dictionaryTypeCode: 'maintenance_period_type',
          languageType: 'zh',
          dictionaryName: '年',
          dictionaryCode: '50',
          sort: 5,
        },
        {
          dictionaryTypeCode: 'machine_type',
          languageType: 'zh',
          dictionaryName: '三色',
          dictionaryCode: '001',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'machine_type',
          languageType: 'zh',
          dictionaryName: '四色',
          dictionaryCode: '002',
          sort: 1,
        },
        {
          dictionaryTypeCode: 'machine_type',
          languageType: 'zh',
          dictionaryName: '五色',
          dictionaryCode: '003',
          sort: 2,
        },
        {
          dictionaryTypeCode: 'machine_type',
          languageType: 'zh',
          dictionaryName: '六色',
          dictionaryCode: '004',
          sort: 3,
        },
        {
          dictionaryTypeCode: 'machine_type',
          languageType: 'zh',
          dictionaryName: '七色',
          dictionaryCode: '005',
          sort: 4,
        },
        {
          dictionaryTypeCode: 'is_maintain',
          languageType: 'zh',
          dictionaryName: '否',
          dictionaryCode: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'is_maintain',
          languageType: 'zh',
          dictionaryName: '是',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'maintenance_status',
          languageType: 'zh',
          dictionaryName: '异常',
          dictionaryCode: '0',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'maintenance_status',
          languageType: 'zh',
          dictionaryName: '正常',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'ink_painting_type',
          languageType: 'zh',
          dictionaryName: '中性',
          dictionaryCode: '1',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'ink_painting_type',
          languageType: 'zh',
          dictionaryName: '水性',
          dictionaryCode: '2',
          sort: 0,
        },
        {
          dictionaryTypeCode: 'ink_painting_type',
          languageType: 'zh',
          dictionaryName: '油性',
          dictionaryCode: '3',
          sort: 0,
        },
      ]);
    }
  }

  async typeList() {
    return await this.dictionaryTypeRepository.find();
  }

  /**
   * 罗列所有配置
   */
  async typePage(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { dictionaryTypeName, dictionaryTypeCode } = entity;

    return await this.dictionaryTypeRepository.findAndCount({
      where: {
        dictionaryTypeName: Like(`%${dictionaryTypeName}%`),
        dictionaryTypeCode: Like(`%${dictionaryTypeCode}%`),
      },
      order: {
        updateTime: 'DESC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });
  }

  /**
   * 新增
   */
  async typeAdd(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const dictionaryType = await this.dictionaryTypeRepository.insert({
      ...data,
      createName: user.nickName,
      createUserName: user.userName,
      updateName: user.nickName,
      updateUserName: user.userName,
    });

    databaseOperationLogList.push({
      type: 'add',
      dataType: 'obj',
      database: 'SysDictionaryType',
      checkOnlyKeyList: [],
      data: dictionaryType,
      whereObj: null,
      remark: `SysDictionaryType表新增数据`,
    });
    await this.operationLogService.add(
      {
        type: 'add',
        msg: `字典管理模块新增字典表类型`,
        databaseOperationLogList,
        remark: `新增字典表类型${data.dictionaryTypeName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 更新
   */
  async typeUpdate(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    await this.dictionaryTypeRepository.update(
      { id: data.id },
      {
        dictionaryTypeName: data.dictionaryTypeName,
        remark: data.remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      }
    );
    databaseOperationLogList.push({
      type: 'update',
      dataType: 'obj',
      database: 'SysDictionaryType',
      checkOnlyKeyList: [],
      data: {
        dictionaryTypeName: data.dictionaryTypeName,
        remark: data.remark,
        updateName: user.nickName,
        updateUserName: user.userName,
      },
      whereObj: { id: data.id },
      remark: `SysDictionaryType表更新字典表类型信息`,
    });
    await this.operationLogService.add(
      {
        type: 'update',
        msg: `字典管理模块更新字典表类型`,
        databaseOperationLogList,
        remark: `更新字典表类型${data.dictionaryTypeName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 删除
   */
  async typeDelete(idList, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const typeCodeList = [];

    for (let i = 0; i < idList.length; i++) {
      const obj = await this.dictionaryTypeRepository.findOne({ where: { id: idList[i] } });

      if (obj) {
        typeCodeList.push(obj.dictionaryTypeCode);
      }
    }
    await this.dictionaryTypeRepository.delete(idList);

    await this.dictionaryRepository.delete({ dictionaryTypeCode: In(typeCodeList) });
    databaseOperationLogList.push({
      type: 'delete',
      dataType: 'array',
      database: 'SysDictionaryType',
      checkOnlyKeyList: [],
      data: null,
      whereObj: idList,
      remark: `SysDictionaryType表删除字典表类型`,
    });
    await this.operationLogService.add(
      {
        type: 'delete',
        msg: `字典管理模块删除字典表类型`,
        databaseOperationLogList,
        remark: `删除字典表类型`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  async typeInfo(data) {
    return await this.dictionaryTypeRepository.findOne({ where: { id: data.id } });
  }

  /**
   * 查询单个
   */
  async info(data, languageType) {
    const { dictionaryTypeCode } = data;

    return await this.dictionaryRepository.find({ where: { dictionaryTypeCode, languageType } });
  }

  async isExistTypeKey(dictionaryTypeCode: string) {
    const result = await this.dictionaryRepository.findOne({ where: { dictionaryTypeCode } });

    if (result) {
      throw new ApiException(10037);
    }
  }

  /**
   * 罗列所有配置
   */
  async page(data) {
    const { pageSize, pageNum, entity = {} } = data;

    const { dictionaryTypeCode, languageType } = entity;

    return await this.dictionaryRepository.findAndCount({
      where: {
        dictionaryTypeCode,
        languageType: Like(`%${languageType}%`),
      },
      order: {
        sort: 'ASC',
      },
      take: pageSize,
      skip: (pageNum - 1) * pageSize,
    });
  }

  /**
   * 新增
   */
  async add(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const dictionary = await this.dictionaryRepository.insert({
      ...data,
      createName: user.nickName,
      createUserName: user.userName,
      updateName: user.nickName,
      updateUserName: user.userName,
    });
    databaseOperationLogList.push({
      type: 'add',
      dataType: 'obj',
      database: 'SysDictionary',
      checkOnlyKeyList: [],
      data: dictionary,
      whereObj: null,
      remark: `SysDictionary表新增数据`,
    });
    await this.operationLogService.add(
      {
        type: 'add',
        msg: `字典信息列表新增字典表`,
        databaseOperationLogList,
        remark: `新增字典表${data.dictionaryName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 更新
   */
  async update(data, user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    const { extend1, extend2, id, dictionaryName, sort, remark, languageType } = data;
    await this.dictionaryRepository.update(
      { id },
      {
        dictionaryName,
        sort,
        remark,
        languageType,
        extend1,
        extend2,
        updateName: user.nickName,
        updateUserName: user.userName,
      }
    );
    databaseOperationLogList.push({
      type: 'update',
      dataType: 'obj',
      database: 'SysDictionary',
      checkOnlyKeyList: [],
      data: {
        dictionaryName,
        sort,
        remark,
        languageType,
        extend1,
        extend2,
        updateName: user.nickName,
        updateUserName: user.userName,
      },
      whereObj: { id },
      remark: `SysDictionary表更新字典表信息`,
    });
    await this.operationLogService.add(
      {
        type: 'update',
        msg: `字典信息列表更新字典表`,
        databaseOperationLogList,
        remark: `更新字典表${data.dictionaryName}`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  /**
   * 删除
   */
  async delete(ids: number[], user, mac, ip, syncHostSqlite) {
    const databaseOperationLogList = [];

    await this.dictionaryRepository.delete(ids);
    databaseOperationLogList.push({
      type: 'delete',
      dataType: 'array',
      database: 'SysDictionary',
      checkOnlyKeyList: [],
      data: null,
      whereObj: ids,
      remark: `SysDictionary表删除字典表信息`,
    });
    await this.operationLogService.add(
      {
        type: 'delete',
        msg: `字典信息列表删除字典表`,
        databaseOperationLogList,
        remark: `删除字典表`,
        mac,
        ip,
        syncHostSqlite: isNaN(Number(syncHostSqlite)) ? 0 : Number(syncHostSqlite),
      },
      user
    );
  }

  async isExistKey(data) {
    const { dictionaryTypeCode, languageType, dictionaryCode } = data;
    const list = await this.dictionaryRepository.find({ where: { dictionaryTypeCode } });
    const result = list.find((item) => {
      return item.languageType == languageType && item.dictionaryCode == dictionaryCode;
    });
    if (result) {
      throw new ApiException(10034);
    }
  }

  async getColumnsList() {
    const entityMetadata = this.dictionaryRepository.metadata;

    const list = entityMetadata.columns.map((column) => {
      return {
        key: column.propertyName,
        comment: column.comment,
      };
    });

    return list;
  }
}
